<template>
  <div class="syn-form-page">
    <!-- 顶部：返回 | 新增/编辑 -->
    <div class="page-header">
      <a-button type="link" class="back" @click="onBack">
        <LeftOutlined class="back-icon" />
        返回
      </a-button>
      <span class="sep">|</span>
      <span class="title">{{ pageTitle }}</span>
    </div>

    <!-- 父级滚动容器 -->
    <div class="content-area">
      <!-- 表单 -->
      <a-form
        ref="formRef"
        :model="form"
        :rules="rules"
        :label-col="{ style: 'width: 88px;' }"
        :wrapper-col="{ style: 'max-width: 720px;' }"
        class="form"
      >
        <a-form-item label="同义词：" name="words">
          <a-input
            v-model:value="form.words"
            placeholder="请输入"
            allow-clear
          />
          <div class="desc">说明：同义词之间请使用“|”分割。</div>
        </a-form-item>

        <a-form-item label="启用状态：">
          <a-radio-group v-model:value="form.enabled">
            <a-radio :value="true">启用</a-radio>
            <a-radio :value="false">停用</a-radio>
          </a-radio-group>
        </a-form-item>
      </a-form>

      <!-- 底部 -->
      <div class="page-footer">
        <div class="footer-inner">
          <a-button class="btn-cancel" @click="onBack">取消</a-button>
          <span class="sep">|</span>
          <a-button
            type="primary"
            class="action"
            :loading="submitting"
            @click="onSubmit"
          >
            确定
          </a-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive, ref, watch, watchEffect, onMounted } from "vue";
import type { FormInstance } from "ant-design-vue";
import { message } from "ant-design-vue";
import { useRoute, useRouter } from "vue-router";
import { LeftOutlined } from "@ant-design/icons-vue";
import {
  createSynonym,
  updateSynonym,
  getSynonymById,
} from "@/api/modules/synonym.api";

type Mode = "create" | "edit";
export type SynonymPayload = { words: string; enabled: boolean };

const props = withDefaults(
  defineProps<{
    mode?: Mode;
    initial?: Partial<
      SynonymPayload & { id?: string | number; status?: "published" | "draft" }
    > | null;
  }>(),
  { mode: "create", initial: null }
);

const emit = defineEmits<{ (e: "submit", payload: SynonymPayload): void }>();
const router = useRouter();
const route = useRoute();

const formRef = ref<FormInstance>();
const submitting = ref(false);

const routeRow = computed(() => {
  const raw = route.query?.row as string | undefined;
  if (!raw) return null;
  try {
    return JSON.parse(decodeURIComponent(raw));
  } catch {
    return null;
  }
});

const currentMode = computed<Mode>(() => {
  if (props.mode && props.mode !== "create") return "edit";
  if ((route.query.mode as string) === "edit") return "edit";
  const anyId =
    (props.initial as any)?.id ??
    (routeRow.value as any)?.id ??
    (route.query.id as string | number | undefined);
  return anyId ? "edit" : "create";
});

/** 当前编辑 id */
const editingId = ref<string | number | null>(null);

/** 表单数据 */
const form = reactive<SynonymPayload>({ words: "", enabled: true });

/** 标题 */
const pageTitle = computed(() =>
  currentMode.value === "edit" ? "编辑" : "新增"
);

/** 校验 */
const rules = {
  words: [
    { required: true, message: "请输入同义词" },
    {
      validator(_: any, v: string) {
        if (!v) return Promise.resolve();
        const cleaned = v
          .replace(/｜/g, "|")
          .split("|")
          .map((s) => s.trim())
          .filter(Boolean);
        return cleaned.length
          ? Promise.resolve()
          : Promise.reject("请输入有效的同义词");
      },
    },
  ],
};

/** 灌表工具 */
function fillFormFromAny(source: any) {
  if (!source) return;
  const words = String(
    source.words ?? source.name ?? source.querys ?? ""
  ).replace(/｜/g, "|");
  const status = source.status;
  form.words = words;
  form.enabled = status ? status === "published" : source.enabled ?? true;
}

function resolveEditingId(): string | number | null {
  return (
    (props.initial as any)?.id ??
    (routeRow.value as any)?.id ??
    (route.query.id as string | number | undefined) ??
    null
  );
}

/** 拉详情并回显 */
async function fetchDetailAndFill(id: string | number) {
  try {
    const res: any = await getSynonymById(id);
    const data = res?.data ?? res;
    fillFormFromAny(data);
  } catch (e: any) {
    message.error(e?.message || "获取详情失败");
  }
}

/** 初始化 */
async function init() {
  if (currentMode.value === "edit") {
    editingId.value = resolveEditingId();
    if (props.initial) fillFormFromAny(props.initial);
    else if (routeRow.value) fillFormFromAny(routeRow.value);
    if (editingId.value != null) await fetchDetailAndFill(editingId.value);
    else message.error("缺少编辑ID");
  } else {
    if (props.initial) fillFormFromAny(props.initial);
  }
}

onMounted(init);

/** 监听路由 id 变化 */
watch(
  () => [route.query.id, route.query.mode, route.query.row],
  async () => {
    await init();
  }
);

/** initial 外部变化时，同步到表单和 id */
watchEffect(() => {
  if (!props.initial) return;
  if (!editingId.value && currentMode.value === "edit") {
    editingId.value = (props.initial as any).id ?? editingId.value;
  }
  fillFormFromAny(props.initial);
});

/** 返回 */
function onBack() {
  const tab = (route.query.tab as string) || "synonym";
  const backTo = route.query.backTo as string;
  if (backTo === "tab") router.push({ path: "/", query: { tab } });
  else router.back();
}

/** 规范化同义词 */
function normalizeWords(input: string) {
  const parts = input
    .replace(/｜/g, "|")
    .split("|")
    .map((s) => s.trim())
    .filter(Boolean);
  return Array.from(new Set(parts)).join("|");
}

/** 提交 */
async function onSubmit() {
  try {
    submitting.value = true;
    await formRef.value?.validate();

    const words = normalizeWords(form.words);
    const status = form.enabled ? "published" : ("draft" as const);
    emit("submit", { words, enabled: form.enabled });

    if (currentMode.value === "edit") {
      if (editingId.value == null) throw new Error("缺少编辑ID");
      await updateSynonym(editingId.value, { querys: words, status });
      message.success("保存成功");
    } else {
      await createSynonym({ querys: words, status });
      message.success("新增成功");
    }

    onBack();
  } catch (err: any) {
    if (err?.errorFields) return;
    message.error(err?.message || "操作失败，请稍后重试");
  } finally {
    submitting.value = false;
  }
}
</script>

<style lang="less" scoped>
@footer-h: 56px;
@safe-bottom: env(safe-area-inset-bottom);
@label-w: 88px; 
@wrap-max: 720px;
@pad-x: 24px;

.syn-form-page {
  font-family: "PingFang SC", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, sans-serif;

  :deep(.ant-*) {
    font-family: inherit;
  }

  /* 占满视口 + 自适应；仅让 .content-area 产生滚动 */
  height: 100%;
  min-height: 100vh;
  min-height: 100dvh;
  position: relative;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  overflow: hidden; 
}

/* 顶部区域 */
.page-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 24px 0;

  .back.ant-btn {
    display: inline-flex;
    align-items: center;
    padding: 0 12px 0 @pad-x;
    height: 24px;
    line-height: 24px;
    font-size: 14px;
    color: #81889c;

    .back-icon {
      color: inherit;
      font-size: 16px;
      line-height: 1;
    }
  }

  .sep {
    height: 24px;
    line-height: 24px;
    color: #d9d9d9;
    user-select: none;
  }

  .title {
    height: 24px;
    line-height: 24px;
    font-weight: 500;
    font-size: 16px;
    color: #000;
  }
}

/* 父级滚动容器 */
.content-area {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;

  padding: 0 0 16px 0;

  /* 自定义滚动条 */
  &::-webkit-scrollbar {
    width: 10px;
    height: 10px;
  }
  &::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.15);
    border-radius: 6px;
    border: 2px solid transparent;
    background-clip: padding-box;
  }
  &::-webkit-scrollbar-thumb:hover {
    background: rgba(0, 0, 0, 0.25);
  }
  &::-webkit-scrollbar-track {
    background: transparent;
  }

  /* Firefox */
  scrollbar-width: thin;
  scrollbar-color: rgba(0, 0, 0, 0.25) transparent;
  scrollbar-gutter: stable;
}

/* 表单主体 */
.form {
  padding: 24px @pad-x 0 85px;

  :deep(.ant-form-item) {
    margin-bottom: 24px;
  }
  :deep(.ant-form-item-label > label) {
    height: 24px;
    line-height: 24px;
    font-size: 14px;
    color: #333;
  }
  :deep(.ant-form-item-control) {
    min-height: 24px;
  }
  .desc {
    color: #8c8c8c;
    margin-top: 6px;
  }
}

/* 底部操作栏 */
.page-footer {
  position: static;
  margin-top: 16px;
  padding: 12px @pad-x calc(12px + @safe-bottom) @pad-x; 
  background: #fff;
  border-top: 1px solid #f0f0f0;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.03);

  .footer-inner {
    max-width: @wrap-max; 
    margin: 0 auto; 
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    flex-wrap: wrap;
    width: 100%;
  }

  .btn-cancel {
    height: 36px;
    padding: 0 16px;
    border-radius: 8px;
    background: #fafafa;
    border: 1px solid #e8e8e8;
    color: #666;
    transition: all 0.2s ease;
  }
  .btn-cancel:hover {
    background: #fff;
    color: #595959;
    border-color: #d9d9d9;
  }

  .action {
    height: 36px;
    padding: 0 20px;
    border-radius: 8px;
    font-weight: 600;
  }

  .sep {
    color: #e5e7eb;
    user-select: none;
    line-height: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    margin: 0 2px;
  }
}

/* 小屏优化 */
@media (max-width: 576px) {
  .syn-form-page {
    padding-left: 12px;
    padding-right: 12px;
  }
  .page-header {
    padding: 16px 0;
  }
  .form {
    padding: 16px 12px 0 12px;
  }

  .page-footer {
    padding-left: 12px;
    padding-right: 12px;

    .footer-inner {
      max-width: 100%;
      justify-content: center; 
      gap: 8px;
    }

    .btn-cancel,
    .action {
      height: 40px;
    }
  }
}
</style>
